package com.xbongbong.pro.service.toolbox.statistic.help;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.thread.TransmittableThreadLocalUtil;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.domain.entity.ChartEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.TimeTypeEnum;
import com.xbongbong.pro.enums.errorcodes.StatisticsServicesErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.statistic.constant.ChartConstant;
import com.xbongbong.pro.statistic.enums.ChartTypeEnum;
import com.xbongbong.pro.statistic.enums.IndicatorRuleEnum;
import com.xbongbong.pro.statistic.enums.RangeSelectionTypeEnum;
import com.xbongbong.pro.statistic.enums.StatisticsTypeEnum;
import com.xbongbong.pro.statistic.enums.SystemCodeEnum;
import com.xbongbong.pro.statistic.enums.ThroughSourcePageEnum;
import com.xbongbong.pro.statistic.model.ChartModel;
import com.xbongbong.pro.statistic.pojo.FiscalYearTimePojo;
import com.xbongbong.pro.statistic.result.pojo.ChartIdPojo;
import com.xbongbong.pro.statistic.result.pojo.ChartPkParamPojo;
import com.xbongbong.pro.statistic.result.pojo.ChartResultBasePojo;
import com.xbongbong.pro.statistic.result.pojo.ChartResultPkPojo;
import com.xbongbong.pro.statistic.result.pojo.ChartResultPojo;
import com.xbongbong.pro.statistic.result.pojo.PanoramaPojo;
import com.xbongbong.pro.statistic.result.pojo.TimeListPojo;
import com.xbongbong.pro.statistic.result.pojo.dto.ChartResultBaseDTO;
import com.xbongbong.pro.statistic.result.pojo.dto.ChartResultDTO;
import com.xbongbong.pro.statistic.result.pojo.dto.DepAndUserDTO;
import com.xbongbong.pro.statistic.result.pojo.dto.PanoramaDTO;
import com.xbongbong.pro.statistic.through.pojo.ResultThroughPojo;
import com.xbongbong.pro.statistic.through.pojo.dto.ResultThroughDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.DepartmentPkEntity;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.model.DepartmentPkModel;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.CompanyStructTypeEnum;
import com.xbongbong.sys.enums.DataPermissionEnum;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * 从原ChartHelp抽离，该help类包含：
 * （1）处理入参dto，封装处理成相应pojo---如下属list、时间等转换
 * （2）入参判断，是否筛选等
 * @author zcp
 * @version v1.0
 * @date 2019/4/4
 * @since v1.0
 */
@Component
public class ChartDtoHelp {
    private static final Logger LOG = LoggerFactory.getLogger(ChartDtoHelp.class);
    @Resource
    private UserModel userModel;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private DepartmentPkModel departmentPkModel;
    @Resource
    private ChartPkRuleHelp chartPkRuleHelp;
    @Resource
    private ChartModel chartModel;
    @Resource
    private CommonHelp commonHelp;

    /**
     *
     * @param chartResultBaseDTO
     * @return void
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public void dealWithIdIn(ChartResultBaseDTO chartResultBaseDTO) throws XbbException {
        List<ChartIdPojo> chartIdIn = chartResultBaseDTO.getChartIdIn();
        if (CollectionUtils.isEmpty(chartIdIn)) {
            throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224082);
        }
        List<Long> sysIdIn = new ArrayList<>();
        List<Long> customIdIn = new ArrayList<>();
        for (ChartIdPojo chartIdPojo : chartIdIn) {
            if (Objects.equals(chartIdPojo.getStatisticsType(), StatisticsTypeEnum.SYSTEM_STATISTIC.getCode())) {
                sysIdIn.add(chartIdPojo.getId());
            } else {
                customIdIn.add(chartIdPojo.getId());
            }
        }
        chartResultBaseDTO.setSysIdIn(sysIdIn);
        chartResultBaseDTO.setCustomIdIn(customIdIn);
    }

    public void dealWithIdIn(ChartResultBasePojo chartResultBasePojo) throws XbbException {
        ChartResultBaseDTO chartResultBaseDTO = new ChartResultBaseDTO();
        chartResultBaseDTO.setChartIdIn(chartResultBasePojo.getChartIdIn());
        dealWithIdIn(chartResultBaseDTO);
        chartResultBasePojo.setSysIdIn(chartResultBaseDTO.getSysIdIn());
        chartResultBasePojo.setCustomIdIn(chartResultBaseDTO.getCustomIdIn());
    }
    /**
     * 生成系统指标的pojo，比较全，包含开始结束时间、分片时间list等
     * @param userEntity 登录员工
     * @param chartResultDTO 前端请求参数
     * @return com.xbongbong.pro.statistic.pojo.ChartResultPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/2/14 9:32
     * @since v1.0
     * @version v1.0
     */
    public ChartResultPojo getChartResultPojo4SystemFull(UserEntity userEntity, ChartResultDTO chartResultDTO) throws XbbException {
        /*--------处理基础参数--------*/
        ChartResultPojo chartResultPojo = getChartResultPojo(userEntity, chartResultDTO, ChartResultPojo.class);
        /*--------把剩余其他参数塞入--------*/
        BeanUtil.copyProperties(chartResultDTO, chartResultPojo);
        /*--------处理各个桶的时间list、以及时间标题--------*/
        FiscalYearTimePojo fiscalYearTimePojo = chartResultPojo.getFiscalYearTimePojo();
        Integer timeType = fiscalYearTimePojo.getTimeType4DefaultMonth();
        int startMonth = fiscalYearTimePojo.getStartMonth();
        //计算startTimeList、endTimeList
        TimeListPojo timeListPojo = FiscalYearHelp.getTimeList(fiscalYearTimePojo, timeType, 0, startMonth);
        BeanUtil.copyProperties(timeListPojo, chartResultPojo);
        //横坐标
        List<String> dateTitleList = FiscalYearHelp.getDateTitleList(timeListPojo, timeType, startMonth);
        chartResultPojo.setDateTitleList(dateTitleList);
        LOG.info("-------------chartResultPojo-------------:"+ chartResultPojo);
        return chartResultPojo;
    }

    /**
     * 生成系统指标的pojo
     *
     * @param userEntity         登录员工
     * @param chartResultBaseDTO 前端请求参数
     * @return com.xbongbong.pro.statistic.result.pojo.ChartResultPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/4/1 21:59
     * @version v1.0
     * @since v1.0
     */
    public ChartResultPojo getChartResultPojo4Base(UserEntity userEntity, ChartResultBaseDTO chartResultBaseDTO) throws XbbException {
        //只封装fiscalYearTimePojo、开始结束时间、dataPermission、userIdIn
        /*--------处理基础参数--------*/
        ChartResultPojo chartResultPojo = getChartResultPojo(userEntity, chartResultBaseDTO, ChartResultPojo.class);
        /*--------把剩余其他参数塞入--------*/
        BeanUtil.copyProperties(chartResultBaseDTO, chartResultPojo);
        return chartResultPojo;
    }
    /**
     * 计算pk参数
     * @param userEntity     登录员工
     * @param chartResultDTO 前端请求参数
     * @return com.xbongbong.pro.statistic.pojo.ChartResultPkPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/3/18 19:16
     * @since v1.0
     * @version v1.0
     */
    public ChartResultPkPojo getChartResultPojo4Pk(UserEntity userEntity, ChartResultDTO chartResultDTO) throws XbbException {
        ChartResultPkPojo chartResultPkPojo = getChartResultPojo(userEntity, chartResultDTO, ChartResultPkPojo.class);
        //把参数pkShowDep等参数copy入pk参数chartResultPkPojo
        BeanUtil.copyProperties(chartResultDTO, chartResultPkPojo);
        //置入部门pk方案相关
        chartResultPkPojo = getIncludeSubAndNo(chartResultPkPojo);
        return chartResultPkPojo;
    }

    /**
     * 获取pk榜范围设置pk结果
     *
     * @param chartResultDTO 请求参数
     * @return com.xbongbong.pro.statistic.pojo.vo.ChartResultPkVO
     * @throws XbbException
     * @author youli.chen
     * @date 2020/9/9 16:47
     * @version v1.0
     * @since v1.0
     */
    public ChartResultPkPojo getChartResultRulePojo4Pk(UserEntity userEntity, ChartResultDTO chartResultDTO, List<ChartEntity> list) throws XbbException {
        ChartResultPkPojo chartResultPkPojo = chartPkRuleHelp.getChartResultRulePojo(userEntity, chartResultDTO, list, ChartResultPkPojo.class);
        // 自定义pk图表中心设置排名数量为100
        if (Objects.equals(chartResultDTO.getStatisticsType(), StatisticsTypeEnum.CUSTOM_STATISTIC.getCode())) {
            chartResultPkPojo.setTop(BasicConstant.CUSTOM_PK_SIZE);
        }
        //把参数pkShowDep等参数copy入pk参数chartResultPkPojo
        BeanUtil.copyProperties(chartResultDTO, chartResultPkPojo);
        //置入部门pk方案相关
        chartResultPkPojo = getIncludeSubAndNo(chartResultPkPojo);
        return chartResultPkPojo;
    }

    /**
     * 设置求一个人的总数的pojo，即只获取自己（userEntity）
     * @param userEntity 员工
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return com.xbongbong.pro.statistic.result.pojo.ChartResultPojo
     * @author zcp
     * @date 2019/5/22 21:20
     * @since v1.0
     * @version v1.0
     */
    public ChartResultPojo getChartResultPojo4OneTotal(UserEntity userEntity, Integer startTime, Integer endTime) {
        String userId = userEntity.getUserId();
        //系统指标枚举在外部设置，此方法只处理基础参数
        ChartResultPojo chartResultPojo = new ChartResultPojo();
        BeanUtil.copyProperties(userEntity, chartResultPojo);
        chartResultPojo.setPlatform(PlatFormEnum.ALL.getMemo());
        chartResultPojo.setCorpid(userEntity.getCorpid());
        chartResultPojo.setUserId(userId);
        chartResultPojo.setUserIdIn(Collections.singletonList(userId));
        chartResultPojo.setCompanyStructType(CompanyStructTypeEnum.USER.getCode());
        chartResultPojo.setCheckedUserId(userId);
        FiscalYearTimePojo fiscalYearTimePojo = new FiscalYearTimePojo();
        fiscalYearTimePojo.setTimeType(TimeTypeEnum.CUSTOM.getCode());
        chartResultPojo.setFiscalYearTimePojo(fiscalYearTimePojo);
        chartResultPojo.setStartTime(startTime);
        chartResultPojo.setEndTime(endTime);
        return chartResultPojo;
    }

    /**
     * 封装全景图参数pojo
     * @param userEntity 登录员工
     * @param panoramaDto 全景图参数dto
     * @return com.xbongbong.pro.statistic.result.pojo.PanoramaPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/6/3 16:12
     * @since v1.0
     * @version v1.0
     */
    public PanoramaPojo getPanoramaPojo(UserEntity userEntity, PanoramaDTO panoramaDto) throws XbbException {
        PanoramaPojo panoramaPojo = BeanUtil.copyProperties(panoramaDto, PanoramaPojo.class, false);
        /*--------处理dataPermission--------*/
        //网关已经处理过dataPermission，无需再次计算
        int dataPermission = userModel.getDataPermission(userEntity, true);
        panoramaPojo.setDataPermission(dataPermission);
        /*--------处理userIdIn：直接获取登录员工的下属userId数组即可--------*/
        //选择员工，将其下属和其取交集--1包含离职员工
        List<String> userIdIn = userModel.getSubIdListByDataPermission(dataPermission, userEntity.getUserId(), userEntity.getCorpid(), BasicConstant.ONE, false);
        panoramaPojo.setUserIdIn(userIdIn);
        return panoramaPojo;
    }
    /**
     * 封装员工/部门pk pojo
     * @param pkType pk类型
     * @param userEntity 登录员工
     * @param chartResultPkPojo pk参数pojo
     * @return com.xbongbong.pro.statistic.result.pojo.ChartPkParamPojo
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public ChartPkParamPojo getChartPkParamPojo(int pkType, UserEntity userEntity, ChartResultPkPojo chartResultPkPojo) throws XbbException {
        ChartPkParamPojo chartPkParamPojo;
        if (pkType == ChartConstant.PK_DEP) {
            //部门pk
            chartPkParamPojo = getChartPkParamPojo4PkDep(userEntity, chartResultPkPojo);
        }else {
            //员工pk
            chartPkParamPojo = getChartPkParamPojo4PkUser(userEntity, chartResultPkPojo);
        }
        return chartPkParamPojo;
    }

    /**
     * pk榜 排名所需数据--比如nameUserMap，nameDepMap等
     * 		app端pk榜无需显示员工所属部门，即无需查询部门表
     * @param userEntity 登录员工
     * @param chartResultPkPojo pk参数pojo
     * @return com.xbongbong.pro.statistic.pojo.ChartPkParamUserPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/3/12 21:37
     * @since v1.0
     * @version v1.0
     */
    private ChartPkParamPojo getChartPkParamPojo4PkUser(UserEntity userEntity, ChartResultPkPojo chartResultPkPojo) throws XbbException {
        CompanyStructTypeEnum companyStructTypeEnum = ifCheckDepOrUser(chartResultPkPojo.getCheckedDepId(), chartResultPkPojo.getCheckedUserId(),chartResultPkPojo.getCheckedDepIdIn(),chartResultPkPojo.getCheckedUserIdIn());
        if (companyStructTypeEnum == CompanyStructTypeEnum.UNKNOWN || companyStructTypeEnum == CompanyStructTypeEnum.USER) {
            //没有筛选or筛选了员工，则置为全公司（pk榜不能筛选）
            chartResultPkPojo.setCheckedDepId(1L);
            chartResultPkPojo.setCheckedUserId("");
        }
        ChartPkParamPojo chartPkParamPojo = new ChartPkParamPojo();
        boolean pkShowDep = chartResultPkPojo.getPkShowDep();
        String corpid = chartResultPkPojo.getCorpid();
        //是否开启“显示离职员工数据”
        Boolean pkLeave = chartResultPkPojo.getPkLeave();
        if (pkLeave == null) {
            pkLeave = companyConfigModel.hasBeenEnable(corpid, CompanyConfigEnum.PK_LEAVE.getAlias(), "1");
        }
        //所有下属
        Integer dataPermission = userModel.getDataPermission(userEntity, true);
        List<String> userIdIn = userModel.getPkUserIdIn(userEntity, pkLeave, dataPermission);
        //要显示的员工list--选择的员工--全公司or某个部门的员工
        List<String> checkUserIdIn = new ArrayList<>(userIdIn);
        //根据筛选封装一些信息
        Map<String, Object> depMap = formatCheck(companyStructTypeEnum, userEntity, chartResultPkPojo.getCheckedDepId(), chartResultPkPojo.getCheckedDepIdIn() ,pkShowDep, pkLeave, checkUserIdIn);
        //筛选的员工信息
        List<UserEntity> userList = userModel.getPkUserList(userEntity, checkUserIdIn, pkLeave);
        //userId--员工姓名
        Map<String, String> nameUserMap = new HashMap<>(userList.size());
        //userId--员工头像
        Map<String, String> avatarUserMap = new HashMap<>(userList.size());
        //userId---员工业务总int型数量
        Map<String, Integer> countUserMap = new HashMap<>(userList.size());
        //userId---员工业务总double型数量
        Map<String, Double> amountUserMap = new HashMap<>(userList.size());
        for (UserEntity user : userList) {
            String uid = user.getUserId();
            String name = user.getName();
            if (Objects.equals(userEntity.getDel(), DelEnum.DELETE.getDel())) {
                name = name + "(" + I18nMessageUtil.getMessage(CommonConstant.LEAVE) + ")";
            }
            nameUserMap.put(uid, name);
            avatarUserMap.put(uid, user.getAvatar());
            countUserMap.put(uid, 0);
            amountUserMap.put(uid, 0d);
        }
        //处理部门信息
        if (pkShowDep) {
            chartPkParamPojo = formatDepInfo(chartPkParamPojo, depMap, userList, checkUserIdIn);
        }
        chartPkParamPojo.setUserIdIn(userIdIn);
        chartPkParamPojo.setCheckUserIdIn(checkUserIdIn);
        chartPkParamPojo.setNameUserMap(nameUserMap);
        chartPkParamPojo.setAvatarUserMap(avatarUserMap);
        chartPkParamPojo.setCountUserMap(countUserMap);
        chartPkParamPojo.setAmountUserMap(amountUserMap);
        if (Objects.equals("ding7d7048dadb92fc7f", userEntity.getCorpid())) {
            LOG.info("performanceFinish4User----userId: " + userEntity.getUserId() + "   chartPkParamPojo:" + chartPkParamPojo);
        }
        return chartPkParamPojo;
    }

    /**
     * pk榜 部门排名所需数据--比如nameDepMap，countDepMap等
     *
     * @param userEntity 登录员工
     * @param chartResultPkPojo pk参数pojo
     * @return com.xbongbong.pro.statistic.pojo.ChartPkParamPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/3/14 20:49
     * @since v1.0
     * @version v1.0
     */
    private ChartPkParamPojo getChartPkParamPojo4PkDep(UserEntity userEntity, ChartResultPkPojo chartResultPkPojo) throws XbbException {
        String corpid = userEntity.getCorpid();
        ChartPkParamPojo chartPkParamPojo = new ChartPkParamPojo();
        //是否开启“显示离职员工数据”
        Boolean pkLeave = chartResultPkPojo.getPkLeave();
        if (pkLeave == null) {
            pkLeave = companyConfigModel.hasBeenEnable(corpid, CompanyConfigEnum.PK_LEAVE.getAlias(), "1");
        }
        //所有下属
        Integer dataPermission = userModel.getDataPermission(userEntity, true);
        List<String> userIdIn = userModel.getPkUserIdIn(userEntity, pkLeave, dataPermission);
        //筛选的员工信息
        List<UserEntity> userList = userModel.getPkUserList(userEntity, userIdIn, pkLeave);

        //部门pk，某一个pk方案包含下属部门和不包含下属部门的
        //包含下属部门的
        Set<Long> includeSubDepIds = chartResultPkPojo.getIncludeSubDepIds();
        //不包含下属部门的
        Set<Long> noIncludeSubDepIds = chartResultPkPojo.getNoIncludeSubDepIds();

        //筛选部门，包含下级部门
        Set<Long> depIdSet = new HashSet<>();
        depIdSet.addAll(includeSubDepIds);
        depIdSet.addAll(noIncludeSubDepIds);
        depIdSet.add(-1L);
        Map<String, Object> tempMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        tempMap.put("corpid", corpid);
        tempMap.put("del", 0);
        //该方案参与pk的部门ids
        tempMap.put("idIn", depIdSet);
        //得到参与pk的部门
        List<DepartmentEntity> pkDepartmentList = departmentModel.findEntitys(tempMap);
        //部门id---部门员工id列表
        Map<Long, Set<String>> depUsersMap = userModel.getDepIdUserIdsMap(userList);

        return setUsersDepsMapForIncludeSub(corpid, pkLeave, chartPkParamPojo, depUsersMap, includeSubDepIds, pkDepartmentList, userIdIn);
    }

    /**
     * 封装员工/部门pk pojo（适用于有利pk榜权限改造后的相关方法）
     * @param pkType pk类型
     * @param userEntity 登录员工
     * @param chartEntity 图表
     * @param chartResultPkPojo pk参数pojo
     * @return com.xbongbong.pro.statistic.result.pojo.ChartPkParamPojo
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public ChartPkParamPojo getChartPkRuleParamPojo(int pkType, UserEntity userEntity, ChartEntity chartEntity, ChartResultPkPojo chartResultPkPojo) throws XbbException {
        ChartPkParamPojo chartPkParamPojo;
        if (pkType == ChartConstant.PK_DEP) {
            //部门pk
            chartPkParamPojo = getChartPkRuleParamPojo4PkDep(userEntity, chartEntity, chartResultPkPojo);
        }else {
            //员工pk
            chartPkParamPojo = getChartPkRuleParamPojo4PkUser(userEntity, chartEntity, chartResultPkPojo);
        }
        return chartPkParamPojo;
    }

    /**
     * pk榜 排名所需数据--比如nameUserMap，nameDepMap等
     * 		app端pk榜无需显示员工所属部门，即无需查询部门表
     * @param userEntity 登录员工
     * @param chartResultPkPojo pk参数pojo
     * @return com.xbongbong.pro.statistic.pojo.ChartPkParamUserPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/3/12 21:37
     * @since v1.0
     * @version v1.0
     */
    public ChartPkParamPojo getChartPkRuleParamPojo4PkUser(UserEntity userEntity, ChartEntity chartEntity, ChartResultPkPojo chartResultPkPojo) throws XbbException {
        CompanyStructTypeEnum companyStructTypeEnum = ifCheckDepOrUser(chartResultPkPojo.getCheckedDepId(), chartResultPkPojo.getCheckedUserId(),chartResultPkPojo.getCheckedDepIdIn(),chartResultPkPojo.getCheckedUserIdIn());
        if (!chartResultPkPojo.getPerformancePk() && (companyStructTypeEnum == CompanyStructTypeEnum.UNKNOWN || companyStructTypeEnum == CompanyStructTypeEnum.USER)) {
            //没有筛选or筛选了员工，则置为全公司（pk榜不能筛选）
            chartResultPkPojo.setCheckedDepId(1L);
            chartResultPkPojo.setCheckedUserId("");
        }
        ChartPkParamPojo chartPkParamPojo = new ChartPkParamPojo();
        boolean pkShowDep = chartResultPkPojo.getPkShowDep();
        String corpid = chartResultPkPojo.getCorpid();
        Integer chartType = chartEntity.getChartType();
        //是否开启“显示离职员工数据”，业绩目标和pk榜分开
        boolean pkLeave;
        if (Objects.equals(chartType, ChartTypeEnum.PERFORMANCE.getCode()) || Objects.equals(chartType, ChartTypeEnum.CUSTOMER_PERFORMANCE.getCode())) {
            pkLeave = chartResultPkPojo.getPkLeave();
        } else {
            pkLeave = companyConfigModel.hasBeenEnable(corpid, CompanyConfigEnum.PK_LEAVE.getAlias(),"1");
        }

        List<String> userIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 参与人list
        List<String> joinUserIdIn = chartResultPkPojo.getUserIdIn();
        // Pk榜可见范围设置，可见数据权限类型，0，数据权限，1，全部数据
        if(Objects.equals(chartEntity.getPowerType(), BasicConstant.ONE) || Objects.equals(chartEntity.getPowerType(),BasicConstant.TWO)){
            // 只能查看参与人
            userIdIn.addAll(joinUserIdIn);
        } else {
            // 当前登陆人对应的角色权限员工信息，与参与人交集
            //所有下属
            Integer dataPermission = userModel.getDataPermission(userEntity, true);
            userIdIn = userModel.getPkUserIdIn(userEntity, pkLeave, dataPermission);
            //筛选的当前登陆人对应的角色权限员工信息
            userIdIn.retainAll(joinUserIdIn);
            // 业绩目标没有选择范围的功能
            if (!(Objects.equals(chartType, ChartTypeEnum.PERFORMANCE.getCode()) || Objects.equals(chartType, ChartTypeEnum.CUSTOMER_PERFORMANCE.getCode()))) {
                //筛选的当前登陆人对应的角色权限员工信息
                userIdIn.retainAll(joinUserIdIn);
            }
        }

        //要显示的员工list--选择的员工--全公司or某个部门的员工
        List<String> checkUserIdIn = new ArrayList<>(userIdIn);
        //根据筛选封装一些信息
        Map<String, Object> depMap = formatCheck(companyStructTypeEnum, userEntity, chartResultPkPojo.getCheckedDepId(), chartResultPkPojo.getCheckedDepIdIn(),pkShowDep, pkLeave, checkUserIdIn);
        //筛选的员工信息
        List<UserEntity> userList = userModel.getPkUserList(userEntity, checkUserIdIn, pkLeave);

        //userId--员工姓名
        Map<String, String> nameUserMap = new HashMap<>(userList.size());
        //userId--员工头像
        Map<String, String> avatarUserMap = new HashMap<>(userList.size());
        //userId---员工业务总int型数量
        Map<String, Integer> countUserMap = new HashMap<>(userList.size());
        //userId---员工业务总double型数量
        Map<String, Double> amountUserMap = new HashMap<>(userList.size());
        for (UserEntity user : userList) {
            String uid = user.getUserId();
            String name = user.getName();
            if (Objects.equals(user.getDel(), DelEnum.DELETE.getDel()) && pkLeave) {
                name = name + "(" + I18nMessageUtil.getMessage(CommonConstant.LEAVE) + ")";
            }
            nameUserMap.put(uid, name);
            avatarUserMap.put(uid, user.getAvatar());
            countUserMap.put(uid, 0);
            amountUserMap.put(uid, 0d);
        }
        //处理部门信息
        if (pkShowDep) {
            chartPkParamPojo = formatDepInfo(chartPkParamPojo, depMap, userList, checkUserIdIn);
        }
        chartPkParamPojo.setUserIdIn(userIdIn);
        chartPkParamPojo.setCheckUserIdIn(checkUserIdIn);
        chartPkParamPojo.setNameUserMap(nameUserMap);
        chartPkParamPojo.setAvatarUserMap(avatarUserMap);
        chartPkParamPojo.setCountUserMap(countUserMap);
        chartPkParamPojo.setAmountUserMap(amountUserMap);
        return chartPkParamPojo;
    }
    /**
     * pk榜 部门排名所需数据--比如nameDepMap，countDepMap等
     *
     * @param userEntity 登录员工
     * @param chartResultPkPojo pk参数pojo
     * @return com.xbongbong.pro.statistic.pojo.ChartPkParamPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/3/14 20:49
     * @since v1.0
     * @version v1.0
     */
    public ChartPkParamPojo getChartPkRuleParamPojo4PkDep(UserEntity userEntity, ChartEntity chartEntity, ChartResultPkPojo chartResultPkPojo) throws XbbException {
        String corpid = userEntity.getCorpid();
        Integer chartType = chartEntity.getChartType();
        ChartPkParamPojo chartPkParamPojo = new ChartPkParamPojo();
        //是否开启“显示离职员工数据”，业绩目标和pk榜分开
        boolean pkLeave;
        if (Objects.equals(chartType, ChartTypeEnum.PERFORMANCE.getCode()) || Objects.equals(chartType, ChartTypeEnum.CUSTOMER_PERFORMANCE.getCode())) {
            pkLeave = chartResultPkPojo.getPkLeave();
        } else {
            pkLeave = companyConfigModel.hasBeenEnable(corpid, CompanyConfigEnum.PK_LEAVE.getAlias(),"1");
        }

        List<UserEntity> userList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<String> userIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 参与人list
        List<String> joinUserIdIn = chartResultPkPojo.getUserIdIn();
        List<UserEntity> joinUserList = userModel.getByUserId(joinUserIdIn, corpid);
        // Pk榜可见范围设置，可见数据权限类型，0，数据权限，1，全部数据
        if(Objects.equals(chartEntity.getPowerType(), BasicConstant.ONE)){
            // 只能查看参与人
            userList.addAll(joinUserList);
            userIdIn.addAll(joinUserIdIn);
        } else {
            //`数据权限` 或者 `全公司top3 + 数据权限` 对于部门pk时，都按照数据权限过滤参与人
            // 当前登陆人对应的角色权限员工信息，与参与人交集
            //所有下属
            Integer dataPermission = userModel.getDataPermission(userEntity, true);
            userIdIn = userModel.getPkUserIdIn(userEntity, pkLeave, dataPermission);
            //筛选的当前登陆人对应的角色权限员工信息
            userList = userModel.getPkUserList(userEntity, userIdIn, pkLeave);
            userList.retainAll(joinUserList);
            userIdIn.retainAll(joinUserIdIn);
        }

        //部门pk，某一个pk方案包含下属部门和不包含下属部门的
        //包含下属部门的
        Set<Long> includeSubDepIds = chartResultPkPojo.getIncludeSubDepIds();
        //不包含下属部门的
        Set<Long> noIncludeSubDepIds = chartResultPkPojo.getNoIncludeSubDepIds();

        //筛选部门，包含下级部门
        Set<Long> depIdSet = new HashSet<>();
        depIdSet.addAll(includeSubDepIds);
        depIdSet.addAll(noIncludeSubDepIds);
        depIdSet.add(-1L);
        Map<String, Object> tempMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        tempMap.put("corpid", corpid);
        tempMap.put("del", 0);
        //该方案参与pk的部门ids
        tempMap.put("idIn", depIdSet);
        //得到参与pk的部门
        List<DepartmentEntity> pkDepartmentList = departmentModel.findEntitys(tempMap);
        //部门id---部门员工id列表
        Map<Long, Set<String>> depUsersMap = userModel.getDepIdUserIdsMap(userList);

        return setUsersDepsMapForIncludeSub(corpid, pkLeave, chartPkParamPojo, depUsersMap, includeSubDepIds, pkDepartmentList, userIdIn);
    }

    /**
     * 设置穿透后的标题、dataPermission、userIdIn
     * @param userEntity 登录员工
     * @param resultThroughDTO 穿透参数dto
     * @param systemCodeEnum 系统指标类型
     * @return com.xbongbong.pro.statistic.through.pojo.ResultThroughPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/4/29 20:41
     * @since v1.0
     * @version v1.0
     */
    public ResultThroughPojo getThroughPojo(UserEntity userEntity, ResultThroughDTO resultThroughDTO, SystemCodeEnum systemCodeEnum) throws XbbException {
        TransmittableThreadLocalUtil.setValue(SaasMarkEnum.SAAS.getCode(), systemCodeEnum.getXbbRefTypeEnum().getCode(), null, resultThroughDTO.getDistributorMark());
        String corpid = userEntity.getCorpid();
        Long checkedDepId = resultThroughDTO.getCheckedDepId();
        String checkedUserId = resultThroughDTO.getCheckedUserId();
        List<Long> checkedDepIdIn = resultThroughDTO.getCheckedDepIdIn();
        List<String> checkedUserIdIn = resultThroughDTO.getCheckedUserIdIn();
        List<DepAndUserDTO> checkedIdIn = resultThroughDTO.getCheckedId();
        /*--------处理title--------*/
        boolean toNow = SystemCodeEnum.ifToNow(systemCodeEnum);
        String timeTitle = timeToTitle(resultThroughDTO, toNow);
        ResultThroughPojo resultThroughPojo = BeanUtil.copyProperties(resultThroughDTO, ResultThroughPojo.class, false);
        if (Objects.equals(TimeTypeEnum.UP_TO_NOW.getCode(),resultThroughDTO.getTimeType())) {
            resultThroughPojo.getFiscalYearTimePojo().setTimeType(TimeTypeEnum.UP_TO_NOW.getCode());
        }
        CompanyStructTypeEnum companyStructTypeEnum = ifCheckDepOrUser(checkedDepId, checkedUserId,checkedDepIdIn,checkedUserIdIn);
        String title = StringConstant.SHORT_BARS;
        switch (companyStructTypeEnum) {
            case USER:
                //多选数组为空 即首页单选
                if(CollectionsUtil.isEmpty(checkedIdIn)){
                    title = getThroughTitleOfUser(checkedUserId,userEntity,resultThroughPojo,corpid);
                }else if(CollectionsUtil.isNotEmpty(checkedUserIdIn)){
                    //多选数组不为空，需要判断用户数量
                    title = checkedUserIdIn.size() > BasicConstant.ONE ? I18nMessageUtil.getMessage(CommonConstant.CUSTOM_SCOPE) : getThroughTitleOfUser(checkedUserIdIn.get(BasicConstant.ZERO),userEntity,resultThroughPojo,corpid);
                }
                break;
            case DEPARTMENT:
                //多选数组为空 即首页单选
                if(CollectionsUtil.isEmpty(checkedIdIn)){
                    title = getThroughTitleOfDep(checkedDepId,corpid);
                }else if(CollectionsUtil.isNotEmpty(checkedDepIdIn)){
                    //多选数组不为空，需要判断部门数量
                    title = checkedDepIdIn.size() > BasicConstant.ONE ? I18nMessageUtil.getMessage(CommonConstant.CUSTOM_SCOPE) : getThroughTitleOfDep(checkedDepIdIn.get(BasicConstant.ZERO),corpid);
                }
                break;
            case ALL:
                title = I18nMessageUtil.getMessage(CommonConstant.CUSTOM_SCOPE);
                break;
            default:
                if (CollectionUtils.isEmpty(checkedUserIdIn) && CollectionUtils.isEmpty(checkedDepIdIn)){
                    title = I18nMessageUtil.getMessage(CommonConstant.COMPANY_WIDE);
                }else {
                    title = I18nMessageUtil.getMessage(CommonConstant.CUSTOM_SCOPE);
                }
                break;
        }
        resultThroughPojo.setName(title);
        //后面还要拼上指标或业务名，如“新增客户”；部分还需要拼数据字典名，如客户行业、客户阶段、机会阶段的穿透等
        resultThroughPojo.setHead(title + timeTitle);
        /*--------处理dataPermission--------*/
        Integer dataPermission = userModel.getDataPermission(userEntity, true);
        resultThroughPojo.setDataPermission(dataPermission);
        /*--------处理userIdIn--------*/
        List<String> userIdIn = new ArrayList<>();
        if (Objects.equals(ThroughSourcePageEnum.WORK_REPORT_DETAIL.getValue(), resultThroughDTO.getSourcePage()) && CompanyStructTypeEnum.USER == companyStructTypeEnum) {
            if(CollectionsUtil.isNotEmpty(checkedUserIdIn)){
                userIdIn.addAll(checkedUserIdIn);
            }else{
                userIdIn.add(checkedUserId);
            }
        } else {
            //处理pk榜设置的参与人
            ChartEntity chartEntity = chartModel.getByKey(resultThroughPojo.getId(), resultThroughPojo.getCorpid());
            resultThroughPojo.setChartEntity(chartEntity);
            boolean flag = true;
            if (Objects.nonNull(chartEntity)) {
                SystemCodeEnum realSystemCodeEnum = SystemCodeEnum.getByCode(chartEntity.getSystemCode());
                if (Objects.equals(realSystemCodeEnum.getIndicatorRuleEnum(), IndicatorRuleEnum.PK)) {
                    flag = false;
                    // 实际参与人
                    userIdIn = chartPkRuleHelp.getUserIdIn4PkThrough(chartEntity, resultThroughDTO, userEntity, dataPermission, checkedDepId, checkedUserId);
                } else if (Objects.equals(realSystemCodeEnum.getIndicatorRuleEnum(), IndicatorRuleEnum.PERFORMANCE)) {
                    // 业绩目标根据配置过滤离职人员
                    if (!commonHelp.isShowPerformLeave(corpid)) {
                        flag = false;
                        userIdIn = getUserIdIn(userEntity, dataPermission, checkedDepId, checkedUserId, checkedIdIn,new ChartResultBaseDTO(),0);
                        // 为空塞一个-1，防止es不过滤
                        if (CollectionUtils.isEmpty(userIdIn)) {
                            userIdIn.add("-1");
                        }
                    }
                }
            }
            if (flag) {
                userIdIn = getUserIdIn(userEntity, dataPermission, checkedDepId, checkedUserId, checkedIdIn,new ChartResultBaseDTO(),1);
            }
        }
        resultThroughPojo.setUserIdIn(userIdIn);
        return resultThroughPojo;
    }

    /**
     * 获取穿透页左上角部门筛选的标题
     *
     * @param checkedDepId 筛选的员工userId
     * @param corpid 登陆用户实体
     * @return java.lang.String
     * @author zyy
     * @date 2022/8/9
     * @version v1.0
     */
    private String getThroughTitleOfDep(Long checkedDepId, String corpid) throws XbbException {
        String title;
        if (checkedDepId == null || checkedDepId == 1) {
            title = I18nMessageUtil.getMessage(CommonConstant.COMPANY_WIDE);
        } else {
            DepartmentEntity departmentEntity = departmentModel.getByKey(checkedDepId, corpid);
            if (departmentEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100067, SystemErrorCodeEnum.API_ERROR_100067.getMsg());
            }
            title = departmentEntity.getName();
        }
        return title;
    }

    /**
     * 获取穿透页左上角人员筛选的标题
     *
     * @param checkedUserId 筛选的员工userId
     * @param userEntity 登陆用户实体
     * @param resultThroughPojo
     * @param corpid
     * @return java.lang.String
     * @author zyy
     * @date 2022/8/9
     * @version v1.0
     */
    private String getThroughTitleOfUser(String checkedUserId, UserEntity userEntity, ResultThroughPojo resultThroughPojo, String corpid) throws XbbException {
        UserEntity resultEntity;
        if (Objects.equals(checkedUserId, userEntity.getUserId())) {
            resultEntity = userEntity;
        } else {
            resultEntity = userModel.getByKeyIngoreDel(checkedUserId, corpid);
            if (resultEntity == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100065, SystemErrorCodeEnum.API_ERROR_100065.getMsg());
            }
        }
        resultThroughPojo.setAvatar(resultEntity.getAvatar());
        return resultEntity.getName();
    }

    /**
     * 封装ChartResultBasePojo，只设置数据权限、下属ids
     * @param chartResultBasePojo 统计请求pojo
     * @param userEntity 员工
     * @author zcp
     * @date 2019/4/15 16:40
     * @since v1.0
     * @version v1.0
     */
    public void setChartResultBaseInfo(ChartResultBasePojo chartResultBasePojo, UserEntity userEntity) throws XbbException {
        /*--------处理dataPermission--------*/
        Integer dataPermission = userModel.getDataPermission(userEntity, true);
        chartResultBasePojo.setDataPermission(dataPermission);
        /*--------处理userIdIn，强制未筛选--------*/
        List<String> userIdIn = getUserIdIn(userEntity, dataPermission, null, "", null, new ChartResultBaseDTO() ,1);
        chartResultBasePojo.setUserIdIn(userIdIn);
    }
    /**
     * 判断角色权限及其筛选情况
     * @param chartResultBasePojo 参数pojo
     * @return boolean true 非超管角色or筛选了部门或员工，false 超管角色且无筛选
     * @author zcp
     * @date 2019/2/19 14:46
     * @since v1.0
     * @version v1.0
     */
    public boolean judgePermissionAndIfCheck(ChartResultBasePojo chartResultBasePojo) {
        //登录员工数据权限
        Integer dataPermission = chartResultBasePojo.getDataPermission();
        //筛选部门id
        Long checkedDepId = chartResultBasePojo.getCheckedDepId();
        //筛选员工id
        String checkedUserId = chartResultBasePojo.getCheckedUserId();
        // 筛选的部门idList
        List<Long> checkedDepIdIn = chartResultBasePojo.getCheckedDepIdIn();
        // 筛选的员工idList
        List<String> checkedUserIdIn = chartResultBasePojo.getCheckedUserIdIn();
        // 业绩目标要特殊处理
        boolean performanceNoLeaveFlag = false;
        if (chartResultBasePojo.getChartEntity() != null) {
            SystemCodeEnum systemCodeEnum = SystemCodeEnum.getByCode(chartResultBasePojo.getChartEntity().getSystemCode());
            performanceNoLeaveFlag = (Objects.equals(systemCodeEnum, SystemCodeEnum.PERFORMANCE_CONTRACT_AMOUNT) || Objects.equals(systemCodeEnum, SystemCodeEnum.PERFORMANCE_PAYMENT_ED)) && !commonHelp.isShowPerformLeave(chartResultBasePojo.getCorpid());
        }
        //超管角色且无筛选的时候，要获取所有人的数据（业绩目标不显示离职人员时跳过）
        boolean flag = Objects.equals(dataPermission, DataPermissionEnum.ALL.getCode()) && ifCheckDepOrUser(checkedDepId, checkedUserId,chartResultBasePojo.getCheckedDepIdIn(),chartResultBasePojo.getCheckedUserIdIn()) == CompanyStructTypeEnum.UNKNOWN && !performanceNoLeaveFlag;
        /*
          注：返回时对flag取反
          当flag=true时，代表超管且无筛选，该方法返回false
          当flag=false时，表示超管筛选or其他角色，该方法返回true
         */
        return !flag;
    }

    /**
     * 判断参与人是否是全公司
     * @param chartEntity 参数pojo
     * @return boolean true 是全公司，false 不是全公司
     * @author zcp
     * @date 2019/2/19 14:46
     * @since v1.0
     * @version v1.0
     */
    public boolean checkJoinRuleIfAll(ChartEntity chartEntity, ChartResultBasePojo chartResultBasePojo) {
        if (chartEntity == null) {
            return false;
        }
        boolean flag = false;
        JSONArray joinRule = chartEntity.getJoinRule();
        JSONArray removeRule = chartEntity.getRemoveRule();

        List<OptionalRangeEntity> ruleData;
        try {
            ruleData = joinRule.toJavaList(OptionalRangeEntity.class);
        } catch (JSONException e) {
            ruleData = new ArrayList<>();
        }

        Set<Long> depIdArray = new HashSet<>();
        for (OptionalRangeEntity pojo : ruleData) {
            String property = pojo.getProperty();
            String id = pojo.getId();

            if (OptionalRangeEnum.DEPT.getValue().equals(property)) {
                // 部门id
                Long longId;
                try {
                    longId = Long.parseLong(id);
                } catch (NumberFormatException e) {
                    longId = null;
                }
                depIdArray.add(longId);
            }
        }
        if(!depIdArray.isEmpty()){
            // 查询全公司，就不用指定useridIn
            if (depIdArray.contains(1L) && CollectionUtils.isEmpty(removeRule)) {
                flag = true;
            }
        }

        // 业绩目标要特殊处理
        boolean performanceNoLeaveFlag = false;
        if (Objects.equals(chartEntity.getChartType(), ChartTypeEnum.PERFORMANCE.getCode()) || Objects.equals(chartEntity.getChartType(), ChartTypeEnum.CUSTOMER_PERFORMANCE.getCode())) {
            SystemCodeEnum systemCodeEnum = SystemCodeEnum.getByCode(chartEntity.getSystemCode());
            performanceNoLeaveFlag = (Objects.equals(systemCodeEnum, SystemCodeEnum.PERFORMANCE_CONTRACT_AMOUNT) || Objects.equals(systemCodeEnum, SystemCodeEnum.PERFORMANCE_PAYMENT_ED)) && !commonHelp.isShowPerformLeave(chartResultBasePojo.getCorpid());
            flag = Objects.equals(chartResultBasePojo.getDataPermission(), DataPermissionEnum.ALL.getCode());
        }
        //筛选部门id
        Long checkedDepId = chartResultBasePojo.getCheckedDepId();
        //筛选员工id
        String checkedUserId = chartResultBasePojo.getCheckedUserId();
        // 查询全公司且无筛选的时候，要获取所有人的数据
        boolean check = flag && Objects.equals(chartResultBasePojo.getDataPermission(), DataPermissionEnum.ALL.getCode()) && ifCheckDepOrUser(checkedDepId, checkedUserId,chartResultBasePojo.getCheckedDepIdIn(),chartResultBasePojo.getCheckedUserIdIn()) == CompanyStructTypeEnum.UNKNOWN && !performanceNoLeaveFlag;

        return !check;
    }

    /**
     * 判断是筛选了部门or员工or没有筛选
     * @param checkedDepId 筛选部门id
     * @param checkedUserId 筛选员工id
     * @param checkedDepIdIn 多选时的部门id数组
     * @param checkedUserIdIn 多选时的员工id数组
     * @return com.xbongbong.sys.enums.CompanyStructTypeEnum UNKNOWN无筛选；DEPARTMENT筛选了部门；USER筛选了员工
     * @author zcp
     * @date 2019/2/19 14:47
     * @since v1.0
     * @version v1.0
     */
    public CompanyStructTypeEnum ifCheckDepOrUser(Long checkedDepId, String checkedUserId,List<Long> checkedDepIdIn, List<String> checkedUserIdIn) {
        if(CollectionsUtil.isEmpty(checkedDepIdIn) && CollectionsUtil.isEmpty(checkedUserIdIn)){
            boolean checkFlag = (checkedDepId != null && checkedDepId.equals(1L))
                    || (checkedDepId == null && StringUtil.isEmpty(checkedUserId));
            if (checkFlag) {
                //没有筛选
                return CompanyStructTypeEnum.UNKNOWN;
            }else {
                if (!StringUtil.isEmpty(checkedUserId)) {
                    //筛选了员工
                    return CompanyStructTypeEnum.USER;
                }else {
                    //筛选了部门
                    return CompanyStructTypeEnum.DEPARTMENT;
                }
            }
        }else{
            if(!CollectionsUtil.isEmpty(checkedDepIdIn) && !CollectionsUtil.isEmpty(checkedUserIdIn)){
                return CompanyStructTypeEnum.ALL;
            }else if(!CollectionsUtil.isEmpty(checkedDepIdIn)){
                //筛选了员工
                return CompanyStructTypeEnum.DEPARTMENT;
            }else if(!CollectionsUtil.isEmpty(checkedUserIdIn)){
                //筛选了员工
                return CompanyStructTypeEnum.USER;
            }else{
                //没有筛选
                return CompanyStructTypeEnum.UNKNOWN;
            }
        }
    }

    /**
     * 判断是否有筛选的部门或人员
     * @param checkedDepIdIn 筛选的部门list
     * @param checkedUserIdIn 筛选的员工list
     * @return USER or DEPARTMENT or UNKNOWN (员工 or 部门 or 未筛选)
     * @author 梅伟丁
     * @date 2022/5/12 0012 9:23:19
     * @version 1.0
     */
    public CompanyStructTypeEnum ifCheckDepInOrUserIn(List<Long> checkedDepIdIn, List<String> checkedUserIdIn) {
        if (CollectionUtils.isNotEmpty(checkedUserIdIn)){
            return CompanyStructTypeEnum.USER;
        }else if (CollectionUtils.isNotEmpty(checkedDepIdIn)){
            return CompanyStructTypeEnum.DEPARTMENT;
        }else {
            return CompanyStructTypeEnum.UNKNOWN;
        }
    }

    public RangeSelectionTypeEnum CheckDepInOrUserIn(List<Long> checkedDepIdIn, List<String> checkedUserIdIn) {
        if (CollectionUtils.isNotEmpty(checkedUserIdIn) && CollectionUtils.isEmpty(checkedDepIdIn)){
            // 如果只有UserIdIn有值，则只筛选了用户
            return RangeSelectionTypeEnum.USER;
        }else if (CollectionUtils.isNotEmpty(checkedDepIdIn) && CollectionUtils.isEmpty(checkedUserIdIn)){
            // 如果只有DepIdIn有值，则只筛选了部门
            return RangeSelectionTypeEnum.DEPARTMENT;
        }else if (CollectionUtils.isNotEmpty(checkedDepIdIn) && CollectionUtils.isNotEmpty(checkedUserIdIn)){
            // 如果两者都有值，则筛选了部门和用户
            return RangeSelectionTypeEnum.ALL;
        }else {
            // 如果都为空，则都没筛选
            return RangeSelectionTypeEnum.UNKNOWN;
        }
    }
    //-------------------private方法-------------------
    /**
     * 获取统计的共有筛选条件：只封装fiscalYearTimePojo、开始结束时间、dataPermission、userIdIn
     * 注：只处理基础字段，其他参数还需要在外部copy进入相应pojo
     * @param userEntity 登录员工
     * @param chartResultBaseDTO 统计请求基础的参数（全参数在相应的实现chartResultBaseDTO的dto内，如chartResultDTO）
     * @param clazz 相应的统计pojo的class，如ChartResultPojo.class、ChartResultPkPojo.class
     * @return T 相应的统计pojo，如ChartResultPojo、ChartResultPkPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/3/18 19:11
     * @since v1.0
     * @version v1.0
     */
    private <T> T getChartResultPojo(UserEntity userEntity, ChartResultBaseDTO chartResultBaseDTO, Class<T> clazz) throws XbbException {
        ChartResultBasePojo chartResultBasePojo = new ChartResultBasePojo();
        /*--------处理时间FiscalYearTimePojo、财年、开始结束时间、开始结束时间list（分片）--------*/
        //设置FiscalYearTimePojo
        FiscalYearTimePojo fiscalYearTimePojo = chartResultBaseDTO.getTimeFilter();
        if(fiscalYearTimePojo == null){
            fiscalYearTimePojo = new FiscalYearTimePojo();
        }
        //财年开始月份
        int startMonth = companyConfigModel.getFiscalStartMonth(userEntity.getCorpid());
        fiscalYearTimePojo.setStartMonth(startMonth);
        Integer timeType = fiscalYearTimePojo.getTimeType4DefaultMonth();
        TimeTypeEnum timeTypeEnum = TimeTypeEnum.getByCode(timeType);
        if (timeTypeEnum == null) {
            timeType = TimeTypeEnum.MONTH.getCode();
        }
        fiscalYearTimePojo.setTimeTypeEnum(timeTypeEnum);
        chartResultBasePojo.setFiscalYearTimePojo(fiscalYearTimePojo);
        Integer startTime = FiscalYearHelp.getStartTime(fiscalYearTimePojo, timeType, startMonth);
        Integer endTime = FiscalYearHelp.getEndTime(fiscalYearTimePojo, startTime, timeType, startMonth);
        //判断起始时间不能大于结束时间
        if (startTime > endTime || (Objects.equals(startTime, endTime) && !fiscalYearTimePojo.getStartTime().equals(fiscalYearTimePojo.getEndTime()))) {
            throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224007, StatisticsServicesErrorCodeEnum.API_ERROR_224007.getMsg(),"，"+I18nMessageUtil.getMessage(I18nStringConstant.END_TIME_REGULATIONS));
        }
        chartResultBasePojo.setStartTime(startTime);
        chartResultBasePojo.setEndTime(endTime);
        /*--------处理dataPermission--------*/
        //网关已经处理过dataPermission，无需再次计算
        int dataPermission = userModel.getDataPermission(userEntity, true);
        chartResultBasePojo.setDataPermission(dataPermission);
        int isShowLeave = 1;
        // 首页业绩目标 && 过滤离职人员
        if(chartResultBaseDTO.getPerformanceFlag() && !commonHelp.isShowPerformLeave(chartResultBaseDTO.getCorpid())){
            isShowLeave = 0;
        }
        /*--------处理userIdIn--------*/
        List<String> userIdIn = getUserIdIn(userEntity, dataPermission, chartResultBaseDTO.getCheckedDepId(), chartResultBaseDTO.getCheckedUserId(),chartResultBaseDTO.getCheckedId(), chartResultBaseDTO,isShowLeave);
        chartResultBasePojo.setUserIdIn(userIdIn);
        /*--------把计算出的基础参数、和剩余其他参数都塞入clazz对应的实体内--------*/
        T resultPojo = BeanUtil.copyProperties(chartResultBasePojo, clazz, false);
        BeanUtil.copyProperties(chartResultBaseDTO, resultPojo, false);
        return resultPojo;
    }

    /**
     * 获取userIdIn
     * @param chartResultDTO   pk入参实体
     * @param chartEntity    图片
     * @param userEntity     登录员工
     * @param dataPermission 数据权限
     * @param checkedDepId   选择的部门id
     * @param checkedUserId  选择的员工id
     * @return java.util.List<java.lang.String> 筛选的员工与下属取过交集后的userIds
     * @author 有利  参照getUserIdIn方法处理pk榜需求，非我所写的方法
     * @date 2019/2/14 9:18
     * @since v1.0
     * @version v1.0
     * @update by zcp 未考虑可见数据范围为全部数据的情况，导致销售等低权限角色无法看到其他参与人的数据
     */
    public List<String> getRuleUserIdIn(ChartResultDTO chartResultDTO,ChartEntity chartEntity, UserEntity userEntity, Integer dataPermission, Long checkedDepId, String checkedUserId,List<String> joins) {
        if(Objects.equals(chartEntity.getPowerType(), BasicConstant.ONE)){
            //可见范围是全部数据时，直接按照参与人
            return joins;
        }
        if(Objects.equals(chartEntity.getPowerType(), BasicConstant.TWO)){
            if(Objects.equals(chartResultDTO.getTop(),3)){
                chartResultDTO.setTop(null);
            }
            //拆分多选时的入参数据
            if(CollectionUtils.isNotEmpty(chartResultDTO.getCheckedId())){
                // 部门、人员多选处理逻辑
                List<String> checkedUserIdIn = new ArrayList<>();
                List<Long> checkedDepIdIn = new ArrayList<>();
                // 将部门id和员工id区分开
                for (DepAndUserDTO depAndUserDTO : chartResultDTO.getCheckedId()) {
                    if (Objects.equals(depAndUserDTO.getProperty(),BasicConstant.USER)){
                        checkedUserIdIn.add(depAndUserDTO.getId());
                    }else if (Objects.equals(depAndUserDTO.getProperty(),BasicConstant.DEPT)){
                        checkedDepIdIn.add(depAndUserDTO.getValue());
                    }
                }
                chartResultDTO.setCheckedUserIdIn(checkedUserIdIn);
                chartResultDTO.setCheckedDepIdIn(checkedDepIdIn);
            }
            //可见范围是全部数据时，直接按照参与人
            return joins;
        }
        //选择员工，将其下属和其取交集--1包含离职员工
        List<String> userIdIn = userModel.getSubIdListByDataPermission(dataPermission, userEntity.getUserId(), userEntity.getCorpid(), BasicConstant.ONE, false);
        if (Objects.equals(dataPermission, DataPermissionEnum.ALL.getCode())) {
            userIdIn.addAll(joins);
        }
        List<DepAndUserDTO> checkedIdIn = chartResultDTO.getCheckedId();
        // 不支持多选的接口checkedIdIn为空，走老逻辑
        if (CollectionUtils.isEmpty(checkedIdIn)){
            if (checkedDepId != null && checkedDepId != 1L) {
                List<Long> depIdIn = new ArrayList<>();
                depIdIn.add(checkedDepId);
                //1包含离职员工、包含隐藏部门
                List<String> checkUserIdIn = userModel.getUserIdsRecursionDep(depIdIn, userEntity.getCorpid(), 1, true);
                //取交集
                userIdIn.retainAll(checkUserIdIn);
            } else if (!StringUtil.isEmpty(checkedUserId)) {
                //看是否是自己下属
                if (userIdIn.contains(checkedUserId)) {
                    userIdIn.clear();
                    userIdIn.add(checkedUserId);
                } else {//不是下属，则置空
                    userIdIn.clear();
                }
            }
        }else {
            // 部门、人员多选处理逻辑
            List<String> checkedUserIdIn = new ArrayList<>();
            List<Long> checkedDepIdIn = new ArrayList<>();
            // 将部门id和员工id区分开
            for (DepAndUserDTO depAndUserDTO : checkedIdIn) {
                if (Objects.equals(depAndUserDTO.getProperty(),BasicConstant.USER)){
                    checkedUserIdIn.add(depAndUserDTO.getId());
                }else if (Objects.equals(depAndUserDTO.getProperty(),BasicConstant.DEPT)){
                    checkedDepIdIn.add(depAndUserDTO.getValue());
                }
            }
            // 存储用户Id和部门下的所有用户id
            List<String> summaryUserIdIn = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(checkedUserIdIn)){
                summaryUserIdIn.addAll(checkedUserIdIn);
            }
            // 查询部门下的人员
            List<String> depUserIdList = userModel.getDepUserIdList(userEntity.getCorpid(), checkedDepIdIn, 1);
            if (CollectionUtils.isNotEmpty(depUserIdList)){
                summaryUserIdIn.addAll(depUserIdList);
            }
            //去重,取交集
            if (CollectionUtils.isNotEmpty(summaryUserIdIn)){
                Set<String> resultIdList = new HashSet<>(summaryUserIdIn);
                summaryUserIdIn.clear();
                summaryUserIdIn.addAll(resultIdList);
                userIdIn.retainAll(summaryUserIdIn);
            }
            chartResultDTO.setCheckedUserIdIn(checkedUserIdIn);
            chartResultDTO.setCheckedDepIdIn(checkedDepIdIn);
        }
        if (userIdIn.size() <= 0) {
            userIdIn.add("-1");
        }
        return userIdIn;
    }

    /**
     * 获取userIdIn
     * @param userEntity     登录员工
     * @param dataPermission 数据权限
     * @param checkedDepId   选择的部门id
     * @param checkedUserId  选择的员工id
     * @param checkedIdIn  多选的的员工、部门id数组
     * @param chartResultBaseDTO  入参实体,防止bean拷贝将数据覆盖为null
     * @param isShowLeave 0默认，不包含离职员工 1包含离职员工
     * @return java.util.List<java.lang.String> 筛选的员工与下属取过交集后的userIds
     * @author zcp
     * @date 2019/2/14 9:18
     * @since v1.0
     * @version v1.0
     */
    public List<String> getUserIdIn(UserEntity userEntity, Integer dataPermission, Long checkedDepId, String checkedUserId, List<DepAndUserDTO> checkedIdIn, ChartResultBaseDTO chartResultBaseDTO, int isShowLeave) {
        //选择员工，将其下属和其取交集--1包含离职员工
        List<String> userIdIn = userModel.getSubIdListByDataPermission(dataPermission, userEntity.getUserId(), userEntity.getCorpid(), isShowLeave, false);
        if (Objects.equals(dataPermission, DataPermissionEnum.ALL.getCode())) {
            //全部数据权限的（签订人为空也统计进去）
            userIdIn.add("");
            userIdIn.add("0");
        }
        // 不支持多选的接口checkedIdIn为空，走老逻辑
        if (CollectionUtils.isEmpty(checkedIdIn)){
            if (checkedDepId != null && checkedDepId != 1L) {
                List<Long> depIdIn = new ArrayList<>();
                depIdIn.add(checkedDepId);
                //1包含离职员工、包含隐藏部门
                List<String> checkUserIdIn = userModel.getUserIdsRecursionDep(depIdIn, userEntity.getCorpid(), isShowLeave, true);
                //取交集
                userIdIn.retainAll(checkUserIdIn);
            } else if (!StringUtil.isEmpty(checkedUserId)) {
                //看是否是自己下属
                if (userIdIn.contains(checkedUserId)) {
                    userIdIn.clear();
                    userIdIn.add(checkedUserId);
                } else {//不是下属，则置空
                    userIdIn.clear();
                }
            }
        }else {
            // 部门、人员多选处理逻辑
            List<String> checkedUserIdIn = new ArrayList<>();
            List<Long> checkedDepIdIn = new ArrayList<>();
            // 将部门id和员工id区分开
            for (DepAndUserDTO depAndUserDTO : checkedIdIn) {
                if (Objects.equals(depAndUserDTO.getProperty(),BasicConstant.USER)){
                    checkedUserIdIn.add(depAndUserDTO.getId());
                }else if (Objects.equals(depAndUserDTO.getProperty(),BasicConstant.DEPT)){
                    checkedDepIdIn.add(depAndUserDTO.getValue());
                }
            }
            // 存储用户Id和部门下的所有用户id
            List<String> summaryUserIdIn = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(checkedUserIdIn)){
                summaryUserIdIn.addAll(checkedUserIdIn);
            }
            // 查询部门下的人员
            List<String> depUserIdList = userModel.getDepUserIdList(userEntity.getCorpid(), checkedDepIdIn, isShowLeave);
            if (CollectionUtils.isNotEmpty(depUserIdList)){
                summaryUserIdIn.addAll(depUserIdList);
            }
            //去重,取交集
            Set<String> resultIdList = new HashSet<>(summaryUserIdIn);
            summaryUserIdIn.clear();
            summaryUserIdIn.addAll(resultIdList);
            userIdIn.retainAll(summaryUserIdIn);
            //设置数据是因为外层调用会进行bean拷贝，将对应数据拷贝到pojo中
            chartResultBaseDTO.setCheckedUserIdIn(checkedUserIdIn);
            chartResultBaseDTO.setCheckedDepIdIn(checkedDepIdIn);
        }
        if (userIdIn.size() <= 0) {
            userIdIn.add("-1");
        }
        return userIdIn;
    }

    /**
     * 获取用户IdList
     * @param userEntity 用户实体
     * @param dataPermission 数据权限
     * @param checkedDepIdIn 筛选的部门数组
     * @param checkedUserIdIn 筛选的人员数组
     * @param isShowLeave 是否展示离职人员 （0不包含离职人员；1，包含离职人员）
     * @return 实际用户IdList
     * @author 梅伟丁
     * @date 2022/5/11 0011 18:51:03
     * @version 1.0
     */
    public List<String> getUserIdIn(UserEntity userEntity, Integer dataPermission,ResultThroughDTO resultThroughDTO, int isShowLeave) {
        String checkedUserId = resultThroughDTO.getCheckedUserId();
        Long checkedDepId = resultThroughDTO.getCheckedDepId();
        List<String> checkedUserIdIn = resultThroughDTO.getCheckedUserIdIn();
        List<Long> checkedDepIdIn = resultThroughDTO.getCheckedDepIdIn();
        // 前端多选传递checkedIdIn，既包括人员，又包括部门
        //选择员工，将其下属和其取交集--1包含离职员工
        List<String> userIdIn = userModel.getSubIdListByDataPermission(dataPermission, userEntity.getUserId(), userEntity.getCorpid(), isShowLeave, false);
        if (Objects.equals(dataPermission, DataPermissionEnum.ALL.getCode())) {
            //全部数据权限的（签订人为空也统计进去）
            userIdIn.add("");
            userIdIn.add("0");
        }
        // 新建一个临时List来存人员Id和筛选部门的人员Id（不包含子部门）
        List<String> summaryUserIdIn = new ArrayList<>();
        if (StringUtil.isNotEmpty(checkedUserId)){
            summaryUserIdIn.add(checkedUserId);
        }
        if (CollectionUtils.isNotEmpty(checkedUserIdIn)){
            summaryUserIdIn.removeAll(checkedUserIdIn);
            summaryUserIdIn.addAll(checkedUserIdIn);
        }
        if (CollectionUtils.isNotEmpty(checkedDepIdIn)){
            // 部门idList
            Set<Long> depIdList = new HashSet<>(checkedDepIdIn);
            if (checkedDepId != null){
                depIdList.add(checkedDepId);
            }
            // 查询部门下的人员
            List<String> depUserIdList = userModel.getDepUserIdList(userEntity.getCorpid(), depIdList, isShowLeave);
            if (depUserIdList != null && depUserIdList.size() > 0){
                // 增加部门人员(取并集)
                summaryUserIdIn.removeAll(depUserIdList);
                summaryUserIdIn.addAll(depUserIdList);
            }
        }
        // 和已知可查看权限的人员取交集
        userIdIn.retainAll(summaryUserIdIn);
        if (userIdIn.size() <= 0) {
            userIdIn.add("-1");
        }
        return userIdIn;
    }

    /**
     * 获取userIdIn
     * @param userEntity     登录员工
     * @param dataPermission 数据权限
     * @param chartResultBasePojo   选择的部门id
     * @param chartResultBaseDTO  选择的员工id
     * @param isShowLeave 0默认，不包含离职员工 1包含离职员工
     * @return java.util.List<java.lang.String> 筛选的员工与下属取过交集后的userIds
     * @author 梅伟丁
     * @date 2022/4/13 15:50
     * @version 1.0
     */
    public List<String> getUserIdIn(UserEntity userEntity, Integer dataPermission,ChartResultBasePojo chartResultBasePojo, ChartResultBaseDTO chartResultBaseDTO, int isShowLeave) {
        Long checkedDepId = chartResultBaseDTO.getCheckedDepId();
        String checkedUserId = chartResultBaseDTO.getCheckedUserId();
        // 前端多选传递checkedIdIn，既包括人员，又包括部门
        List<DepAndUserDTO> checkedIdIn = chartResultBaseDTO.getCheckedId();
        //选择员工，将其下属和其取交集--1包含离职员工
        List<String> userIdIn = userModel.getSubIdListByDataPermission(dataPermission, userEntity.getUserId(), userEntity.getCorpid(), isShowLeave, false);
        if (Objects.equals(dataPermission, DataPermissionEnum.ALL.getCode())) {
            //全部数据权限的（签订人为空也统计进去）
            userIdIn.add("");
            userIdIn.add("0");
        }
        // 如果checkedIdIn为空，说明是支持单选，如果checkedIdIn不为空，说明改成了多选
        if (CollectionUtils.isEmpty(checkedIdIn)){
            if (checkedDepId != null && checkedDepId != 1L) {
                List<Long> depIdIn = new ArrayList<>();
                depIdIn.add(checkedDepId);
                //1包含离职员工、包含隐藏部门
                List<String> checkUserIdIn = userModel.getUserIdsRecursionDep(depIdIn, userEntity.getCorpid(), isShowLeave, true);
                //取交集
                userIdIn.retainAll(checkUserIdIn);
            } else if (!StringUtil.isEmpty(checkedUserId)) {
                //看是否是自己下属
                if (userIdIn.contains(checkedUserId)) {
                    userIdIn.clear();
                    userIdIn.add(checkedUserId);
                } else {//不是下属，则置空
                    userIdIn.clear();
                }
            }
        }else {
            // 现在搜索添加多选，前端通过checkedIdIn传过来，且不包括下属部门
            List<String> checkedUserIdIn = new ArrayList<>();
            List<Long> checkedDepIdIn = new ArrayList<>();
            // 部门idList
            Set<Long> depIdList = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            // 将部门id和员工id区分开
            for (DepAndUserDTO depAndUserDTO : checkedIdIn) {
                if (Objects.equals(depAndUserDTO.getProperty(),BasicConstant.USER)){
                    checkedUserIdIn.add(depAndUserDTO.getId());
                }else if (Objects.equals(depAndUserDTO.getProperty(),BasicConstant.DEPT)){
                    depIdList.add(depAndUserDTO.getValue());
                    checkedDepIdIn.add(depAndUserDTO.getValue());
                }
            }
            // 新建一个临时List来存人员Id和筛选部门的人员Id（不包含子部门）
            List<String> summaryUserIdIn = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(checkedUserIdIn)){
                summaryUserIdIn.addAll(checkedUserIdIn);
            }
//            // 将筛选的人员与查找的人取交集
//            userIdIn.retainAll(checkedUserIdIn);
            // 查询部门下的人员
            List<String> depUserIdList = userModel.getDepUserIdList(userEntity.getCorpid(), depIdList, isShowLeave);
            if (depUserIdList != null && depUserIdList.size() > 0){
                // 增加部门人员(取并集)
                summaryUserIdIn.removeAll(depUserIdList);
                summaryUserIdIn.addAll(depUserIdList);
            }
            if (CollectionUtils.isNotEmpty(summaryUserIdIn)){
                userIdIn.retainAll(summaryUserIdIn);
            }
            // 将前端给的部门和人员分开，存储到对应位置
            chartResultBasePojo.setCheckedUserIdIn(checkedUserIdIn);
            chartResultBasePojo.setCheckedDepIdIn(checkedDepIdIn);
            chartResultBaseDTO.setCheckedUserIdIn(checkedUserIdIn);
            chartResultBaseDTO.setCheckedDepIdIn(checkedDepIdIn);
        }
        if (userIdIn.size() <= 0) {
            userIdIn.add("-1");
        }
        return userIdIn;
    }

    /**
     * 获取到方案内的部门id，并分成两种：
     * includeSubDepIds：包含下属部门的
     * noIncludeSubDepIds：不包含下属部门的
     * @param chartResultPkPojo 部门pk参数
     * @return com.xbongbong.pro.statistic.pojo.ChartResultPkPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/3/25 15:33
     * @since v1.0
     * @version v1.0
     */
    private ChartResultPkPojo getIncludeSubAndNo(ChartResultPkPojo chartResultPkPojo) throws XbbException {
        if (chartResultPkPojo.getPkType() != ChartConstant.PK_DEP) {
            //非部门pk，则无需处理
            return chartResultPkPojo;
        }
        DepartmentPkEntity departmentPkEntity = departmentPkModel.getByKey(chartResultPkPojo.getDepartmentPkId(), chartResultPkPojo.getCorpid());
        if (departmentPkEntity == null) {
            throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224020, StatisticsServicesErrorCodeEnum.API_ERROR_224020.getMsg(), I18nMessageUtil.getMessage(CommonConstant.SCHEME));
        }
        //获取部门及下属部门
        JSONArray depIncludeSub = departmentPkEntity.getDepIncludeSub();
        //没有设置参与pk的部门
        if (depIncludeSub == null || depIncludeSub.size() == 0) {
            throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224021, StatisticsServicesErrorCodeEnum.API_ERROR_224021.getMsg());
        }
        //包含下属部门的
        Set<Long> includeSubDepIds = new HashSet<>();
        //不包含下属部门的
        Set<Long> noIncludeSubDepIds = new HashSet<>();
        //方案内是否有参与pk的部门id数据，true 有，false 无。（比如只创建了方案，但还未给该方案设置参与pk的部门）
        boolean flag = false;
        for (Object object : depIncludeSub) {
            JSONObject depObj = (JSONObject) object;
            Long depId = StringUtil.StringToLong(depObj.getString("id"));
            Boolean ifIncludeSub = Boolean.valueOf(depObj.getString("includeSub"));
            if (!flag) {
                //有参与pk的部门id
                flag = true;
            }
            if (ifIncludeSub) {
                //包含下属部门
                includeSubDepIds.add(depId);
            } else {
                //不包含下属部门
                noIncludeSubDepIds.add(depId);
            }
        }
        if (!flag) {
            throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224021, StatisticsServicesErrorCodeEnum.API_ERROR_224021.getMsg());
        }
        //包含下属部门的
        chartResultPkPojo.setIncludeSubDepIds(includeSubDepIds);
        //不包含下属部门的
        chartResultPkPojo.setNoIncludeSubDepIds(noIncludeSubDepIds);
        return chartResultPkPojo;
    }
    /**
     * 处理筛选部门的情况：根据筛选封装一些信息
     * @param companyStructTypeEnum 是否筛选标记枚举
     * @param userEntity 登录员工
     * @param checkedDepId 筛选的部门id
     * @param checkedDepIdIn 多选的部门id数组
     * @param pkShowDep 是否处理部门信息
     * @param pkLeave 是否开启“显示离职员工数据”
     * @param checkUserIdIn 塞入筛选的员工ids
     * @return java.util.Map<java.lang.String,java.lang.Object>
     * @author zcp
     * @date 2019/3/12 20:15
     * @since v1.0
     * @version v1.0
     */
    private Map<String, Object> formatCheck(CompanyStructTypeEnum companyStructTypeEnum, UserEntity userEntity, Long checkedDepId,List<Long> checkedDepIdIn ,boolean pkShowDep, boolean pkLeave, List<String> checkUserIdIn) {
        String corpid = userEntity.getCorpid();
        Map<String, Object> depMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //0默认，不包含离职员工		1包含离职员工
        int viewPermission = pkLeave ? 1 : 0;
        //筛选部门，包含下级部门
        Set<Long> depIdSet = new HashSet<>();
        if (companyStructTypeEnum == CompanyStructTypeEnum.DEPARTMENT) {

            if(!CollectionsUtil.isEmpty(checkedDepIdIn)){
                //多选部门时，不递归获取子部门
                depIdSet.addAll(checkedDepIdIn);
            }else {
                //如果筛选部门，则为该部门，否则得到登录员工所属所有部门
                List<Long> depIdIn = Arrays.asList(checkedDepId);
                //1包含离职员工、包含隐藏部门
                depIdSet.addAll(departmentModel.getSubDepIdList(corpid, depIdIn, true));
            }
            List<String> depUserIdList = userModel.getDepUserIdList(corpid, depIdSet, viewPermission);
            if (depUserIdList == null) {
                checkUserIdIn.clear();
            }else {
                checkUserIdIn.retainAll(depUserIdList);
            }
            depIdSet.add(-1L);
            depMap.put("idIn", depIdSet);
        } else if (pkShowDep && !userModel.isBoss(userEntity)) {
            //没有筛选时，获取userEntity主管的所有部门
            List<Long> belongDepList = userModel.getUserManageDeptIdList(userEntity, true);
            depIdSet.addAll(departmentModel.getSubDepIdList(corpid, belongDepList, true));
            depIdSet.add(-1L);
            depMap.put("idIn", depIdSet);
        }
        depMap.put("corpid", corpid);
        depMap.put("del", DelEnum.NORMAL.getDel());
        return depMap;
    }

    private Map<String, Object> formatCheck(CompanyStructTypeEnum companyStructTypeEnum, UserEntity userEntity, ChartResultPkPojo chartResultPkPojo, boolean pkShowDep, boolean pkLeave, List<String> checkUserIdIn) {
        String corpid = userEntity.getCorpid();
        Map<String, Object> depMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> checkedDepIdIn = chartResultPkPojo.getCheckedDepIdIn();
        //0默认，不包含离职员工		1包含离职员工
        int viewPermission = pkLeave ? 1 : 0;
        //筛选部门，包含下级部门
        Set<Long> depIdSet = new HashSet<>();
        if (companyStructTypeEnum == CompanyStructTypeEnum.DEPARTMENT) {
            //如果筛选部门，则为该部门，否则得到登录员工所属所有部门\
            // 新增pk榜多部门选择（兼容之前的逻辑，如果checkedDepIdIn不为空，则为新逻辑(不包括下属部门)）
            if (CollectionUtils.isEmpty(checkedDepIdIn)){
                List<Long> depIdIn = Arrays.asList(chartResultPkPojo.getCheckedDepId());
                depIdSet.addAll(departmentModel.getSubDepIdList(corpid, depIdIn, true));
            }else {
                depIdSet.addAll(checkedDepIdIn);
            }
            //1包含离职员工、包含隐藏部门
            List<String> depUserIdList = userModel.getDepUserIdList(corpid, depIdSet, viewPermission);
            if (depUserIdList == null) {
                checkUserIdIn.clear();
            }else {
                checkUserIdIn.retainAll(depUserIdList);
            }
            depIdSet.add(-1L);
            depMap.put("idIn", depIdSet);
        } else if (pkShowDep && !userModel.isBoss(userEntity)) {
            //没有筛选时，获取userEntity主管的所有部门
            List<Long> belongDepList = userModel.getUserManageDeptIdList(userEntity, true);
            depIdSet.addAll(departmentModel.getSubDepIdList(corpid, belongDepList, true));
            depIdSet.add(-1L);
            depMap.put("idIn", depIdSet);
        }
        depMap.put("corpid", corpid);
        depMap.put("del", DelEnum.NORMAL.getDel());
        return depMap;
    }
    /**
     * 封装部门信息
     * @param chartPkParamPojo 员工pk需要的参数pojo，此方法内主要用于置入部门相关信息
     * @param depMap 查询部门map
     * @param userList 员工list
     * @param checkUserIdIn 塞入筛选的员工ids
     * @return com.xbongbong.pro.statistic.pojo.ChartPkParamPojo
     * @author zcp
     * @date 2019/3/12 21:24
     * @since v1.0
     * @version v1.0
     */
    private ChartPkParamPojo formatDepInfo(ChartPkParamPojo chartPkParamPojo, Map<String, Object> depMap, List<UserEntity> userList, List<String> checkUserIdIn) {
        //要显示的部门list
        List<DepartmentEntity> departmentList = departmentModel.findEntitys(depMap);
        //部门id---部门名称（无部门则key = 1L）
        Map<Long, String> nameDepMap = new HashMap<>(departmentList.size());
        //userId---所属部门id列表（无部门则value = [1L]）
        Map<String, Set<Long>> userDepSetMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //部门id---部门员工id列表（无部门则key = [1L]）
        Map<Long, Set<String>> depUsersMap = userModel.getDepIdUserIdsMap(userList);
        String corpName = "-";
        //赋入用于处理无部门员工
        List<String> tempCheckUserIdIn = new ArrayList<>(checkUserIdIn);
        for (DepartmentEntity departmentEntity : departmentList) {
            Long depId = departmentEntity.getId();
            String depName = departmentEntity.getName();
            if(departmentEntity.getId().equals(1L)){
                //全公司的设为“无部门”
                corpName = depName;
            }
            //部门id---部门名称
            nameDepMap.put(depId, depName);
            Set<String> userIds = depUsersMap.get(depId);
            if (userIds == null || userIds.isEmpty()) {
                continue;
            }
            tempCheckUserIdIn.removeAll(userIds);
            //此时userDepMap都是已设置部门的员工id 和 所属部门id的对应关系
            for (String uid : userIds) {
                Set<Long> didSet = userDepSetMap.get(uid);
                if (didSet == null) {
                    didSet = new HashSet<>();
                }
                didSet.add(depId);
                //userId---所属部门id列表
                userDepSetMap.put(uid, didSet);
            }
        }
        nameDepMap.put(1L, corpName);
        //处理剩余无部门的情况
        for (String uid : tempCheckUserIdIn) {
            //处理无部门的情况
            Set<Long> didSet = userDepSetMap.get(uid);
            //说明没有部门
            if (didSet == null) {
                didSet = new HashSet<>();
                didSet.add(1L);
                //无部门
                userDepSetMap.put(uid, didSet);
                Set<String> userIds = depUsersMap.get(1L);
                if (userIds == null) {
                    userIds = new HashSet<>();
                }
                userIds.add(uid);
                depUsersMap.put(1L, userIds);
            }
        }
        chartPkParamPojo.setDepartmentList(departmentList);
        chartPkParamPojo.setNameDepMap(nameDepMap);
        chartPkParamPojo.setUserDepSetMap(userDepSetMap);
        chartPkParamPojo.setDepUsersMap(depUsersMap);
        return chartPkParamPojo;
    }
    /**
     * 设置员工所属的部门ids，以及部门（及其下属部门）包含的员工userIds
     * 部门业绩PK时，计算PK方案内包含下级部门的dep所包含的员工（把他们的下属部门也计算入内）
     * 需要循环每一个包含下属部门的includeSubDepIds，因为要得到这些部门及它的下属部门内所有的员工ids  即，要得到对应关系
     * @param corpid 公司id
     * @param pkLeave 是否开启“显示离职员工数据”
     * @param chartPkParamPojo pk需要的参数pojo，此方法内主要用于置入部门相关信息
     * @param depUsersMap 部门id---部门员工id列表（无部门则key = [1L]）
     * @param includeSubDepIds 方案内包含下属部门的部门ids
     * @param pkDepartmentList 参与pk的部门实体list
     * @param userIdIn 下属员工list
     * @return com.xbongbong.pro.statistic.pojo.ChartPkParamPojo
     * @author zcp
     * @date 2019/3/14 19:04
     * @since v1.0
     * @version v1.0
     */
    private ChartPkParamPojo setUsersDepsMapForIncludeSub(String corpid, boolean pkLeave, ChartPkParamPojo chartPkParamPojo, Map<Long, Set<String>> depUsersMap, Set<Long> includeSubDepIds, List<DepartmentEntity> pkDepartmentList, List<String> userIdIn){
        Set<String> noRepeatCheckUserIdIn = new HashSet<>();
        //部门id---部门名称	（无部门则key = 1L）
        Map<Long, String> nameDepMap = new HashMap<>(pkDepartmentList.size());
        //部门id---部门总业务数量
        Map<Long, Integer> countDepMap = new HashMap<>(pkDepartmentList.size());
        //部门id---部门总业务总金额
        Map<Long, Double> amountDepMap = new HashMap<>(pkDepartmentList.size());
        //userId---所属部门id列表（无部门则value = [1L]）
        Map<String, Set<Long>> userDepSetMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        int viewPermission = pkLeave ? 1 : 0;
        //需要循环每一个包含下属部门的includeSubDepIds，因为要得到这些部门及它的下属部门内所有的员工ids  即，要得到对应关系
        for (DepartmentEntity departmentEntity : pkDepartmentList) {
            Long depId = departmentEntity.getId();
            String depName = departmentEntity.getName();
            nameDepMap.put(depId, depName);
            countDepMap.put(depId, 0);
            amountDepMap.put(depId, 0d);
            //部门id---部门员工id列表（无部门则key = [1L]）
            Set<String> userIds = depUsersMap.get(depId);
            //处理包含子部门的情况
            Boolean includeSub = includeSubDepIds != null && includeSubDepIds.contains(depId);
            if (includeSub) {
                Set<Long> depIdIn = new HashSet<>();
                depIdIn.add(depId);
                //该部门以及该部门的所有下级部门
                depIdIn.addAll(departmentModel.getSubDepIdList(corpid, depIdIn, true));
                userIds = (userIds == null) ? new HashSet<>() : userIds;
                userIds.addAll(userModel.getDepUserIdList(corpid, depIdIn, viewPermission));
                depUsersMap.put(depId, userIds);
            }
            if (userIds == null || userIds.size() == 0) {
                continue;
            }
            //-----------处理userDepSetMap
            //与自己下属取交集
            userIds.retainAll(userIdIn);
            noRepeatCheckUserIdIn.addAll(userIds);
            //此时userDepMap都是已设置部门的员工id 和 所属部门id的对应关系
            for (String uid : userIds) {
                //userId -- 员工所属部门id列表
                Set<Long> depSet = userDepSetMap.get(uid);
                if (depSet == null) {
                    depSet = new HashSet<>();
                }
                depSet.add(depId) ;
                userDepSetMap.put(uid, depSet);
            }
        }
        chartPkParamPojo.setCheckUserIdIn(new ArrayList<>(noRepeatCheckUserIdIn));
        chartPkParamPojo.setNameDepMap(nameDepMap);
        chartPkParamPojo.setCountDepMap(countDepMap);
        chartPkParamPojo.setAmountDepMap(amountDepMap);
        chartPkParamPojo.setUserDepSetMap(userDepSetMap);
        chartPkParamPojo.setDepUsersMap(depUsersMap);
        return chartPkParamPojo;
    }
    /**
     * 计算穿透后的时间标题
     * @param resultThroughDTO 穿透参数dto
     * @param toNow 是否是截至到当前时间的概念，false否，true是
     * @return java.lang.String
     * @throws XbbException
     * @author zcp
     * @date 2019/4/29 20:38
     * @since v1.0
     * @version v1.0
     */
    private String timeToTitle(ResultThroughDTO resultThroughDTO, boolean toNow) throws XbbException {
        StringBuilder title = new StringBuilder();
        TimeTypeEnum timeTypeEnum = TimeTypeEnum.getByCode(resultThroughDTO.getTimeType());
        Integer startTime = resultThroughDTO.getStartTime();
        Integer endTime = resultThroughDTO.getEndTime();
        if (toNow) {
            if (endTime == null) {
                throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224007, StatisticsServicesErrorCodeEnum.API_ERROR_224007.getMsg(), "，", I18nMessageUtil.getMessage(I18nStringConstant.END_TIME_NOT_EMPTY));
            }
            title.append(DateUtil.getString(startTime, DateUtil.SDFDate));
            String endDay = DateUtil.getString(endTime - 1, DateUtil.SDFDate);
            title.append(I18nMessageUtil.getMessage(CommonConstant.END_TO)).append(endDay);
        } else {
            if (timeTypeEnum == null || startTime == null || endTime == null) {
                throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224007, String.format(StatisticsServicesErrorCodeEnum.API_ERROR_224007.getMsg(), ""));
            }
            if (startTime > endTime) {
                throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224007, StatisticsServicesErrorCodeEnum.API_ERROR_224007.getMsg(), "，",I18nMessageUtil.getMessage(I18nStringConstant.END_TIME_REGULATIONS));
            }
            String endDay = DateUtil.getString(endTime - 1, DateUtil.SDFDate);
            switch (timeTypeEnum) {
                case WEEK:
                case WEEK_LAST:
                    //本周、上周
                    title.append(timeTypeEnum.getName());
                    break;
                case DAY:
                case DAY_LAST:
                    //今日、昨日、某天
                    title.append(DateUtil.getString(startTime, DateUtil.SDFDate));
                    break;
                default:
                    String startDay = DateUtil.getString(startTime, DateUtil.SDFDate);
                    title.append(startDay).append(I18nMessageUtil.getMessage(CommonConstant.TO)).append(endDay);
                    break;
            }
        }
        return title.toString();
    }
    /**
     * 生成系统指标的pojo，比较全，包含开始结束时间、分片时间list等
     * @param chartResultDTO 前端请求参数
     * @return com.xbongbong.pro.statistic.pojo.ChartResultPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/2/14 9:32
     * @since v1.0
     * @version v1.0
     */
    public ChartResultPojo getChartResultPojo4Dw(ChartResultDTO chartResultDTO) throws XbbException {
        /*--------处理基础参数--------*/
        ChartResultPojo chartResultPojo = getChartResultPojo4Dw(chartResultDTO, ChartResultPojo.class);
        /*--------把剩余其他参数塞入--------*/
        BeanUtil.copyProperties(chartResultDTO, chartResultPojo);
        /*--------处理各个桶的时间list、以及时间标题--------*/
        FiscalYearTimePojo fiscalYearTimePojo = chartResultPojo.getFiscalYearTimePojo();
        Integer timeType = fiscalYearTimePojo.getTimeType4DefaultMonth();
        int startMonth = fiscalYearTimePojo.getStartMonth();
        //计算startTimeList、endTimeList
        TimeListPojo timeListPojo = FiscalYearHelp.getTimeList(fiscalYearTimePojo, timeType, 0, startMonth);
        BeanUtil.copyProperties(timeListPojo, chartResultPojo);
        //横坐标
        List<String> dateTitleList = FiscalYearHelp.getDateTitleList(timeListPojo, timeType, startMonth);
        chartResultPojo.setDateTitleList(dateTitleList);
        LOG.info("-------------chartResultPojo-------------:"+ chartResultPojo);
        return chartResultPojo;
    }
    /**
     * 获取统计的共有筛选条件：只封装fiscalYearTimePojo、开始结束时间、dataPermission、userIdIn
     * 注：只处理基础字段，其他参数还需要在外部copy进入相应pojo
     * @param chartResultBaseDTO 统计请求基础的参数（全参数在相应的实现chartResultBaseDTO的dto内，如chartResultDTO）
     * @param clazz 相应的统计pojo的class，如ChartResultPojo.class、ChartResultPkPojo.class
     * @return T 相应的统计pojo，如ChartResultPojo、ChartResultPkPojo
     * @throws XbbException
     * @author zcp
     * @date 2019/3/18 19:11
     * @since v1.0
     * @version v1.0
     */
    private <T> T getChartResultPojo4Dw(ChartResultBaseDTO chartResultBaseDTO, Class<T> clazz) throws XbbException {
        ChartResultBasePojo chartResultBasePojo = new ChartResultBasePojo();
        /*--------处理时间FiscalYearTimePojo、财年、开始结束时间、开始结束时间list（分片）--------*/
        //设置FiscalYearTimePojo
        FiscalYearTimePojo fiscalYearTimePojo = chartResultBaseDTO.getTimeFilter();
        if(fiscalYearTimePojo == null){
            fiscalYearTimePojo = new FiscalYearTimePojo();
        }
        //财年开始月份
        int startMonth = companyConfigModel.getFiscalStartMonth(chartResultBaseDTO.getCorpid());
        fiscalYearTimePojo.setStartMonth(startMonth);
        Integer timeType = fiscalYearTimePojo.getTimeType4DefaultMonth();
        TimeTypeEnum timeTypeEnum = TimeTypeEnum.getByCode(timeType);
        if (timeTypeEnum == null) {
            timeType = TimeTypeEnum.MONTH.getCode();
        }
        fiscalYearTimePojo.setTimeTypeEnum(timeTypeEnum);
        chartResultBasePojo.setFiscalYearTimePojo(fiscalYearTimePojo);
        Integer startTime = FiscalYearHelp.getStartTime(fiscalYearTimePojo, timeType, startMonth);
        Integer endTime = FiscalYearHelp.getEndTime(fiscalYearTimePojo, startTime, timeType, startMonth);
        //判断起始时间不能大于结束时间
        if (startTime > endTime || (Objects.equals(startTime, endTime) && !fiscalYearTimePojo.getStartTime().equals(fiscalYearTimePojo.getEndTime()))) {
            throw new XbbException(StatisticsServicesErrorCodeEnum.API_ERROR_224007, StatisticsServicesErrorCodeEnum.API_ERROR_224007.getMsg(),"，"+I18nMessageUtil.getMessage(I18nStringConstant.END_TIME_REGULATIONS));
        }
        chartResultBasePojo.setStartTime(startTime);
        chartResultBasePojo.setEndTime(endTime);
        /*--------把计算出的基础参数、和剩余其他参数都塞入clazz对应的实体内--------*/
        T resultPojo = BeanUtil.copyProperties(chartResultBasePojo, clazz, false);
        BeanUtil.copyProperties(chartResultBaseDTO, resultPojo, false);
        return resultPojo;
    }
}
